package mx.com.crowdgine.game;

import java.nio.FloatBuffer;
import java.util.LinkedList;

import org.w3c.dom.Node;

import com.jogamp.common.nio.Buffers;

import javax.media.opengl.GLAutoDrawable;

import mx.com.crowdgine.app.JoglApplication;
import mx.com.crowdgine.assetloader.Asset;
import mx.com.crowdgine.assetloader.OBJModelAsset;
import mx.com.crowdgine.assetloader.audio.AudioManager;
import mx.com.crowdgine.camera.Camera;
import mx.com.crowdgine.camera.FPCamera;
import mx.com.crowdgine.camera.JoglCamera;
import mx.com.crowdgine.camera.ScriptedCamera;
import mx.com.crowdgine.crowds.CrowdSystem;
import mx.com.crowdgine.crowds.samples.SimpleCrowds;
import mx.com.crowdgine.crowds.samples.StadiumCrowds;
import mx.com.crowdgine.display.animation.glsl.GLSLAnimation;
import mx.com.crowdgine.display.animation.mocap.MocapAnimation;
import mx.com.crowdgine.entity.Entity;
import mx.com.crowdgine.entity.geometry.Cube;
import mx.com.crowdgine.entity.geometry.Plane;
import mx.com.crowdgine.generator.TerrainGenerator;
import mx.com.crowdgine.particlesystem.ParticleSystem;
import mx.com.crowdgine.particlesystem.jogl.SineWaveParticleSystem;
import mx.com.crowdgine.particlesystem.jogl.SnowParticleSystem;
import mx.com.crowdgine.util.math.Vector3f;
import mx.com.crowdgine.util.xml.XMLReader;

public class CrowdgineGame extends JoglApplication {
	
	public Entity cube;
	public Entity plane;
	public Asset mrTCrowd;
	public Asset mrTAnimated;
	public Asset stadium;
	
	
	public TerrainGenerator terrain;
	
	public ParticleSystem particleSystem;
	public CrowdSystem simpleCrowd;
	
	public float x;
	public float time;
	public int timeStep;
	
	// Time between frames
	public float elapsedTime = 0;
	private long lastTime = 0;
	private float dt;
	boolean translateFlag = false;//QUITAME!!!!!
	
	AudioManager bgMusic;
	
	public CrowdgineGame(String frameName, int width, int height){
		super(frameName, width, height);
	}
	
	
	public static void main(String [] args){
		
		//------XMLReader Usage Test--------------
		/*XMLReader parser = new XMLReader("Assets/Config/CrowdgineConfig.xml");
		if(parser.isXMLParsed()){
			parser.printHashMap();
			parser.printNode(parser.getXMLNode(XMLReader.ASSETS_TAG));
			System.out.println(XMLReader.buildHashMap(parser.getXMLNode(XMLReader.ASSETS_TAG)));
			System.out.println();
			
			Node crowds = parser.getXMLNode(XMLReader.CROWDS_TAG);
			System.out.println("Crowds " + XMLReader.getNodeInformation(crowds));
			HashMap<String, Node> crowdsHash = XMLReader.buildHashMap(crowds);
			
			//Node number = crowdsHash.get("number")
			
			Node groups = crowdsHash.get("groups");
			System.out.println("Groups " + XMLReader.getNodeInformation(groups));
			
			HashMap<String, Node> groupsHash = XMLReader.buildHashMap(groups);
			System.out.println(groupsHash);
			
			Node group_1 = groupsHash.get("group_1");
			System.out.println("Group_1 " + XMLReader.getNodeInformation(group_1));
		}
		
		parser = new XMLReader("Assets/XML/genericTest.xml");
		if(parser.isXMLParsed()){
			parser.printHashMap();
			parser.printNode(parser.getXMLNode("test"));
			System.out.println(XMLReader.buildHashMap(parser.getXMLNode("test")));
		}*/
		//----------------------------------------
		
		CrowdgineGame game= new CrowdgineGame("Crowdgine Blissful Game",640,480);
		game.start();
	}
	
	@Override
	public void initialize(){
		super.initialize();
		ScriptedCamera sc = new ScriptedCamera();
		sc.setPosition(new Vector3f(320,-200,240));
		//sc.setYaw(90f);
		//addAndSetCamera(sc);
		addAndSetCamera(new JoglCamera());
		//addCamera(new JoglCamera());
		x=0.1f;
		time=0;
		timeStep = 0;
		//cube = new Cube(5, 2, 9, Vector3f.ZERO);
		plane = new Plane(new Vector3f(350,0,0), new Vector3f(0,0,200), new Vector3f(50,5,100), new Vector3f(0,1,0));
		//plane.translate(new Vector3f(5,0,0));
		//addEntity(cube);
		addEntity(plane);
		
		particleSystem = new SnowParticleSystem();
		addParticleSystem(particleSystem);
		
		
		
		XMLReader parser = new XMLReader("Assets/Config/CrowdgineConfig.xml");
		Node crowds = null;
		if(parser.isXMLParsed()){
			crowds = parser.getXMLNode(XMLReader.CROWDS_TAG);
		}
		if(crowds != null)
			simpleCrowd = new StadiumCrowds(crowds, true);
		else
			simpleCrowd = new SimpleCrowds(256, false);
		
		
		
		mrTCrowd = new OBJModelAsset();
//		mrT.setAnimation(new GLSLAnimation("Assets/shaders/wobbleVertex.glsl", "Assets/shaders/wobbleFragment.glsl"));
//		mrT.setAnimation(new MocapAnimation("Assets/Mocap/12.asf", "Assets/Mocap/13_39.amc", "Assets/Models/casual01TMP.obj", "Assets/Textures/joints.bmp", "Assets/Shaders/mocapVertex.glsl", "Assets/Shaders/mocapFragment.glsl", "Assets/Textures/maleTexture.bmp"));
		mrTCrowd.setAnimation(new MocapAnimation("Assets/Mocap/12.asf", "Assets/Mocap/13_39.amc", "Assets/Models/casual01TMP.obj", "Assets/Textures/joints.bmp", "Assets/Shaders/mocapVertex2.glsl", "Assets/Shaders/mocapFragment2.glsl", "Assets/Textures/maleTexture.bmp"));
		// to see current work directory uncomment the following line
		// System.out.println(new File(".").getAbsolutePath());
		mrTCrowd.setAssetName("Assets/models/casual01TMP");
		simpleCrowd.addAsset(mrTCrowd);
		
		
		mrTAnimated =  new OBJModelAsset();
		mrTAnimated.setAnimation(new MocapAnimation("Assets/Mocap/12.asf", "Assets/Mocap/13_39.amc", "Assets/Models/casual01TMP.obj", "Assets/Textures/joints.bmp", "Assets/Shaders/mocapVertex.glsl", "Assets/Shaders/mocapFragment.glsl", "Assets/Textures/maleTexture.bmp"));
		mrTAnimated.setAssetName("Assets/models/casual01TMP");
		addAsset(mrTAnimated);
		
		stadium = new OBJModelAsset();
		stadium.setAssetName("Assets/Models/stadium");
		stadium.setAnimation(new GLSLAnimation("Assets/Shaders/sizeVertex.glsl", "Assets/Shaders/sizeFragment.glsl"));
		
		addAsset(stadium);
		
		
		elapsedTime = 0; 
		lastTime = System.currentTimeMillis();
		
		/*mrT = new OBJModelAsset();
		mrT.setAnimation(new MocapAnimation("Assets/Mocap/12.asf", "Assets/Mocap/09_11.amc", "Assets/Models/casual01TMP.obj", "Assets/Textures/joints.bmp", "Assets/Shaders/mocapVertex.glsl", "Assets/Shaders/mocapFragment.glsl", "Assets/Textures/maleTexture.bmp"));
		// to see current work directory uncomment the following line
		// System.out.println(new File(".").getAbsolutePath());
		mrT.setAssetName("Assets/Models/casual01TMP");
		addAsset(mrT);*/
		
		
	}
	
	@Override
	public void init(GLAutoDrawable drawable){
		super.init(drawable);
		System.out.println("Init Drawable");
		
		XMLReader parser = new XMLReader("Assets/Config/CrowdgineConfig.xml");
		Node terrainNode = null;
		if(parser.isXMLParsed()){
			terrainNode = parser.getXMLNode(XMLReader.TERRAIN_TAG);
		}
		if(terrainNode != null){
			terrain = new TerrainGenerator(terrainNode, true);
			LinkedList<Entity> terrainEntities = terrain.getEntities();
			for(Entity tE : terrainEntities){
				addEntity(tE);
			}
		}
		
		particleSystem.init(drawable);
		simpleCrowd.initCrowd(drawable);
		
		if(simpleCrowd.isInitialized())
			addCrowdSystem(simpleCrowd);
		
		bgMusic = new AudioManager("Assets/Audio/crowd.wav");
	}
	
	@Override
	public void update(GLAutoDrawable drawable){
		super.update(drawable);
		//plane.translate(new Vector3f(x,0,0));
		//x+=0.0001;
		//time+=0.1;
		x+=0.0001;
		time+=0.1;
		
		
        //Get the amount of time from one frame to another
        dt = (float)(System.currentTimeMillis() - lastTime) / 1000.0f;
        elapsedTime += dt;
        lastTime = System.currentTimeMillis();
        
        simpleCrowd.updateCrowd(dt);
        particleSystem.simulate(dt);	
        
   /*     float light[] = new float[]{1.0f,1.0f,1.0f};
		FloatBuffer lightData = Buffers.newDirectFloatBuffer(light);
		
		stadium.getAnimation().setParameter("LightPos0", lightData, 4, 4);*/
        bgMusic.play();
        
        /*if(translateFlag == false && stadium != null && stadium.isLoaded()){
        	((OBJModelAsset)stadium).translate(new Vector3f(320,0,240));
        	translateFlag = true;
        }*/
	}
	
}